package com.mntp.iodemo.biodemo;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 同步阻塞IO模型
 *
 * BIO服务端代码
 * 雨雀：https://www.yuque.com/manongtuopin/gumu94/do8rrzuzqo9h4epn
 */
public class BioServerTest {
    /**
     * 1.创建一个服务端ServerSocket，监听9999端口,底层干了3件事情
     *  （1）创建一个socket=3的文件描述符
     *  （2）.bind(3,9999)把socket=3的绑定到9999端口
     *  （3）.开启监听 listen(3...)=0,此时服务端已经准备完毕了
     * 2.调用accept方法，阻塞等待客户端连接
     *   （1）客户端调用accept建立连接的时候,服务端会创建一个socket=5的文件描述符(因为服务端是接收多个客户端，所以每个客户端连接都要创建一个新的socket与之对应)
     * 3.从客户端读取数据，底层实现
     *     （1）服务端会调用內核api的 read 或者 recvfrom(5,"hello\n")=6 是数据长度6个字节
     * 4.向客户端写数据，底层实现
     *     （1）服务端会调用內核api的  sendto(5,"hello client：......" )  向客户端发送了一个消息
     */
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        BufferedReader in = null;
        BufferedWriter out = null;
        try {
            // 1.创建一个服务端ServerSocket，监听9999端口
            serverSocket = new ServerSocket(9999);
            System.out.println("server start success , port is 9999 ......");
            System.out.println("server waiting  for client connection......");
            // 2.调用accept方法，阻塞等待客户端连接 Waiting for client connection
            final Socket socket = serverSocket.accept();
            System.out.println("a new client connection successfully!");
            //从客户端读取数据
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //向客户端写数据
            out = new BufferedWriter(new java.io.OutputStreamWriter(socket.getOutputStream()));
            String line = in.readLine();
            if (line == null) {
                return;
            }
            System.out.println(">>>>>msg from client is:   " + line);
            out.write("hello client：" + socket.getInputStream() + " i am server \n");
            out.flush();

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                serverSocket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            try {
                in.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            try {
                out.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }


    }
}
